#pragma once
#include<memory>
#include<mutex>
#include<iostream>

using namespace std;
template<typename T>
class Singleton {
protected:
	Singleton() = default;
	Singleton(const Singleton<T>&) = delete;
	Singleton& operator = (const Singleton<T>& st) = delete;

	static std::shared_ptr<T> _instance;
public:
	~Singleton() {
		std::cout << "this is singleton destruct" << std::endl;
	}
	static std::shared_ptr<T> GetInstance() {
		static std::once_flag s_flag;//只会在第一次调用Gentinstance的时候执行初始化,以后不管怎么调用都没反应,生命周期还很长,局部静态变量特性;
		std::call_once(s_flag, [&]() {//call_once将s_flag标记,保证这个lambda函数只会被调用一次,第二次的时候检测标记发现调用过就不执行了
			//从而保证线程安全
			_instance = shared_ptr<T>(new T);
			});
			return _instance;
	}
	void PrintAddress() {
		std::cout << _instance->get() << endl;
	}
};

template<typename T>//模板特性:在被实例化的时候才会去被检测
std::shared_ptr<T> Singleton<T>::_instance = nullptr;
